home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Storage / Bento / CM / TOCEnts.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  33.3 KB  |  650 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:         TOCEnts.h  
  3.  
  4.     Contains:    Container Manager TOC Entry Interfaces
  5.  
  6.     Written by:    Ira L. Ruben
  7.  
  8.     Owned by:    Ed Lai
  9.  
  10.     Copyright:    © 1991-1994 by Apple Computer, Inc., all rights reserved.
  11.  
  12.     Change History (most recent first):
  13.  
  14.          <2>     8/26/94    EL        #1181622 Ownership update.
  15.          <3>     5/10/94    EL        #1162327. ValueDoNotFree is no longer
  16.                                                     needed.
  17.          <2>     3/31/94    EL        Export cmFreeProperties. #1150214
  18.          <1>      2/3/94    EL        first checked in
  19.          <2>      1/6/94    EL        Add ValueDoNotFree to value flag.
  20.  
  21.     To Do:
  22. */
  23.  
  24. /*---------------------------------------------------------------------------*
  25.  |                                                                           |
  26.  |                            <<<  TOCEnts.h   >>>                           |
  27.  |                                                                           |
  28.  |                   Container Manager TOC Entry Interfaces                  |
  29.  |                                                                           |
  30.  |                               Ira L. Ruben                                |
  31.  |                                 12/02/91                                  |
  32.  |                                                                           |
  33.  |                  Copyright Apple Computer, Inc. 1991-1994                 |
  34.  |                           All rights reserved.                            |
  35.  |                                                                           |
  36.  *---------------------------------------------------------------------------*
  37.  
  38.  This file contains the interfaces to the manipulation routines to handle TOC objects
  39.  below the object level.  The objects and the means to get at them are maintained in
  40.  TOCObjects.c.  The split is done this way to keep the accessing of objects separate from
  41.  the stuff represented by those objects.  See  TOCObjs.c   for complete details.
  42. */
  43.  
  44. #ifndef __TOCENTRIES__
  45. #define __TOCENTRIES__
  46.  
  47.  
  48. #include <setjmp.h>
  49. #include <stdio.h>
  50.  
  51. /*------------------------------------------------------------------------------------*
  52.  | W A R N I N G - - -> this header as well as  TOCObjs.h   and  TOCEnts.h   all have |
  53.  |                      mutual references.  The include order is NOT arbitrary.  It's |
  54.  |                      the only one that works!  Even with it we have to do some     |
  55.  |                      forward struct pointer references of the form "struct foo *p" |
  56.  *------------------------------------------------------------------------------------*/
  57.  
  58. #ifndef __CMTYPES__
  59. #include "CMTypes.h"
  60. #endif
  61. #ifndef __CM_API_TYPES__
  62. #include "CMAPITyp.h"
  63. #endif
  64. #ifndef __TOCOBJECTS__
  65. #include "TOCObjs.h"   
  66. #endif
  67. #ifndef __CONTAINEROPS__
  68. #include "Containr.h"  
  69. #endif
  70. #ifndef __DYNAMICVALUES__
  71. #include "DynValus.h"     
  72. #endif
  73. #ifndef __GLOBALNAMES__
  74. #include "GlbNames.h"   
  75. #endif
  76. #ifndef __UPDATING__
  77. #include "Update.h"  
  78. #endif
  79. #ifndef __LISTMGR__
  80. #include "ListMgr.h"
  81. #endif
  82.  
  83. struct TOCProperty;
  84. struct TOCValueHdr;
  85. struct DynValueHdrExt;
  86.  
  87.                                                                  CM_CFUNCTIONS
  88.  
  89.                                                         /*-------------------*
  90.                                                          | Values (segments) |
  91.                                                          *-------------------*
  92.  
  93.                                 W A R N I N G !!
  94.  
  95. This union may be the source of portability problems on machines that don't have 4-byte
  96. longs, 2-byte shorts, and 1-byte bytes.  Byte ordering may also lead to portability        
  97. problems.                                                                                                                                                                */
  98.  
  99. union TOCValueBytes {                                    /* Layout of value/length fields:                                    */
  100.     struct {                                                        /*         value if not immediate(not explicitly here):*/
  101.         CM_ULONG value;                                        /*                offset to value if not immediate                */
  102.         CM_ULONG valueLen;                                /*                value length if not immediate                     */
  103.     } notImm;
  104.     
  105.     struct {                                                        /*         value for a global name                                            */
  106.         CM_ULONG                     offset;                    /*                offset to value in container                        */
  107.         struct GlobalName    *globalNameSymbol;/*            ptr value for a global name (in memory)    */
  108.     } globalName;
  109.     
  110.     union {                                                            /*        actual value if immediate placed here:            */
  111.         CM_UCHAR     ucharsValue[2*sizeof(CM_ULONG)];/*value if immediate unsigned char(s)            */
  112.         CM_ULONG     ulongValue;                            /*                value if immediate unsigned long                */
  113.         CM_USHORT ushortValue;                        /*                value if immediate unsigned short                */
  114.         CM_UCHAR    ubyteValue;                            /*                value if immediate unsigned byte                */
  115.         void              *ptrValue;                            /*                value if immediate pointer                            */
  116.     } imm;
  117. };
  118. typedef union TOCValueBytes TOCValueBytes, *TOCValueBytesPtr;
  119.  
  120. struct TOCValue {                                            /* Layout of a TOC type's value:                                    */
  121.     ListLinks                     valueLinks;            /*        links to next/prev value         (must be first)    */
  122.     struct TOCValueHdr *theValueHdr;        /*        ptr back to ValueHdr "owning" this value        */
  123.     ContainerPtr               container;                /*        ptr to "owning" container control block            */
  124.     CMValueFlags            flags;                        /*        flags                                                                                */
  125.     TOCValueBytes           value;                        /*        value and length or immediate value                    */
  126.     CM_ULONG                     logicalOffset;        /*        original (unedited) logical offset                    */
  127. };
  128. typedef struct TOCValue TOCValue, *TOCValuePtr;
  129.  
  130. enum ConstValueType {                                    /* Data types used to copy data into TOCValue's:    */
  131.     Value_NotImm,                                                /*        not immediate    ==> value and valueLen            */
  132.     Value_GlobalName,                                        /*        global name ptr  ==> in-memory str ptr             */
  133.     Value_Imm_Chars,                                        /*        immediate, chars ==> ucharsValue                        */
  134.     Value_Imm_Long,                                            /*        immediate, long     ==> ulongValue                            */
  135.     Value_Imm_Short,                                        /*        immediate, short ==> ushortValue                        */
  136.     Value_Imm_Byte                                            /*        immediate, byte  ==> ushortValue                        */
  137. };
  138. typedef enum ConstValueType ConstValueType;
  139.  
  140. /* Note: The "owning" container control block of a value segment may not necessarily be    */
  141. /*             the same as the one that owns the value header of the segments (shwon below).    */
  142. /*              The owner of the value header is always the container control block associated    */
  143. /*              with the TOC for that container.  The owner of a value segment, however, may        */
  144. /*              be a DIFFERENT TOC due to one container "editing" another.     Editing is also        */
  145. /*              the reason for the originalOffset field in value segments.  Using it we can        */
  146. /*             determine inserts, deletes, and overwrites.                                                                        */
  147.  
  148.  
  149.                                                             /*---------------*
  150.                                                              | Value Headers |
  151.                                                              *---------------*/
  152.                                                              
  153. struct TOCValueHdr {                                    /* Layout of a TOC property type:                                    */
  154.     ListLinks                            valueHdrLinks;    /*        links to next/prev value hdr (must be first)*/
  155.     struct TOCProperty     *theProperty;        /*        ptr to "owning" property                                        */
  156.     ListHdr                                valueList;            /*        list of actual values                                                */
  157.     CMObjectID                        typeID;                    /*        the value's type ID                                                    */
  158.     ContainerPtr                  container;            /*        ptr to "owning" container control block            */
  159.     CM_ULONG                        size;                        /*        total current size of the value data                */
  160.     CM_ULONG                         logicalSize;        /*        original (unupdated) size of the value data    */
  161.     CM_USHORT                        valueFlags;            /*        flags indicating stuff about the value            */
  162.     CMGeneration                generation;            /*        generation number                                                        */
  163.     CM_ULONG                       useCount;                /*        count of nbr of times "used"                                */
  164.     CMRefCon                          valueRefCon;        /*        user's value refCon                                                    */
  165.     TouchedListEntryPtr touch;                    /*         ptr to updating touched list entry                    */
  166.     union {                                                            /*         this field depends on kind of value hdr:        */
  167.         struct TOCValueHdr         *dynValue;    /*                ptr to dynamic value hdr or NULL                */
  168.         struct DynValueHdrExt *extensions;/*                ptr to dynamic value hdr extensions            */
  169.     } dynValueData;                                            /*        [extensions only when it's a dynamic value]    */
  170.     union {                                                            /*        references recorded by this value                        */
  171.         TOCObjectPtr refDataObject;                /*                associated ref object; NULL if no refs    */
  172.         ListHdrPtr      refShadowList;                /*                or shadow list of the actual data                */
  173.     } references;                                                /*                (refShadowList only in recording value)    */
  174. };
  175. typedef struct TOCValueHdr TOCValueHdr, *TOCValueHdrPtr;
  176.  
  177. struct DynValueHdrExt {                                /* Extensions to TOCValueHdr for a dynamic value:    */
  178.     TOCValueHdrPtr       baseValue;                /*        ptr to base value of this dynamic value            */
  179.     DynamicValueVector dynValueVector;    /*        dynamic value handler vector                                */
  180.     CMMetaHandler             metaHandler;            /*        metahandler to get handler addresses                */
  181. };
  182. typedef struct DynValueHdrExt DynValueHdrExt, *DynValueHdrExtPtr;
  183.  
  184. /* Some of following valueFlags echo the flags field a TOCValue entry. That is because     */
  185. /* a CMValue "refNum" that an API user is given and in turn given back to us is a             */
  186. /* pointer to a TOCValueHdr.  It is sometimes more convenient therefore to check the         */
  187. /* kind of value we have by looking at the header then "going out" to the value. In all */
  188. /* but continued values there is only one TOCValue entry on the valueList anyway.  So     */
  189. /* echoing is more efficient than always going after the tail or head (they're the same)*/
  190. /* of a valueList just to see the flags and the kind of value.                                                    */
  191.  
  192. #define    ValueDeleted            0x0001U            /* valueFlags: 1 ==> deleted value                                */
  193. #define ValueContinued        0x0002U            /*                              ==> continued                                        */
  194. #define ValueGlobal                0x0004U            /*                             ==> global name                                    */
  195. #define ValueImmediate        0x0008U            /*                             ==> immediate value                            */
  196. #define ValueOffPropChain    0x0800U            /*                             ==> dynamic value off prop chain    */
  197. #define ValueDynamic            0x1000U            /*                             ==> dynamic value                                */
  198. #define ValueUndeletable    0x2000U            /*                             ==> can't be deleted                         */
  199. #define ValueProtected        0x4000U            /*                             ==> locked/protected value                */
  200. #define ValueDefined            0x8000U            /*                             ==> fully defined (in read only)    */
  201.  
  202. /* Note: ValueUndeletable and ValueProtected are levels of protection bits. They protect*/
  203. /*              a value from certain operations like writing to them or deleting them. The            */
  204. /*             ValueProtected is a superset of ValueUndeletable.  ValueUndeletable says just     */
  205. /*             than ond only that, i.e., you can do anything to it except delete it.                    */
  206.  
  207. #define ValueCstFlags (ValueDefined       | /* These flags are generally set in various     */\
  208.                                              ValueProtected     | /* places and must remain set when we do the    */\
  209.                                              ValueUndeletable | /* standard echoing of the value flags in            */\
  210.                                              ValueDynamic         | /* cmSetTOCValueHdrFlags() in TOCEntries.c.        */\
  211.                                              ValueOffPropChain|    /* This mask is used there.                                        */\
  212.                                              ValueContinued)
  213.                                              
  214. /* In order to make dealing with dynamic values easier, the following macros are                */
  215. /* provided.  One is a more self-documented test to see if a TOCValueHdr is indeed a         */
  216. /* dynamic value, while the other allows simpler notational access to a dynamic value        */
  217. /* header's extension fields.                                                                                                                        */
  218.  
  219. #define IsDynamicValue(v)    ((((TOCValueHdrPtr)(v))->valueFlags & ValueDynamic) != 0)
  220.  
  221. #define DYNEXTENSIONS(v)                             /* to make access to extensions a "little" easier!*/\
  222.                                                      (((TOCValueHdrPtr)(v))->dynValueData.extensions)
  223.  
  224.  
  225.                                                                     /*------------*
  226.                                                                      | Properties |
  227.                                                                      *------------*/
  228.  
  229. struct TOCProperty {                                    /* Layout of a TOC object property:                                */
  230.     ListLinks          propertyLinks;                    /*        links to next/prev property (must be first)    */
  231.     TOCObjectPtr theObject;                            /*         ptr to "owning" object                                            */
  232.     CMObjectID      propertyID;                        /*        the property's ID                                                         */
  233.     ListHdr             valueHdrList;                    /*         list of the property's values                                */
  234. };
  235. typedef struct TOCProperty TOCProperty, *TOCPropertyPtr;
  236.         
  237.     
  238. CM_USHORT cmSetTOCValueHdrFlags(TOCValueHdrPtr theValueHdr, const CM_USHORT flags);
  239.     /*
  240.     This routine is used to echo the settings of a value's flags in the value header which
  241.     "owns" the value (TOCValue's are on a list whose header is in a TOCValueHdr).  This is
  242.     done because a CMValue "refNum" that an API user is given and in turn given back to us
  243.     is a pointer to a TOCValueHdr.  It is sometimes more convenient therefore to check the
  244.     kind of value we have by looking at the header then "going out" to the value. In all but
  245.     continued values there is only one TOCValue entry on the valueList anyway.  So echoing
  246.     is more efficient than always going after the tail or head (they're the same) of a
  247.     valueList just to see the flags and the kind of value.    
  248.     
  249.     The function updates the valueFlags field in the passed TOCValueHdr according to the
  250.     value flags also passed.  The updated valueFlags are also returned as the function
  251.     result.
  252.     */
  253.     
  254.  
  255. TOCValueBytesPtr cmSetValueBytes(const ContainerPtr container,
  256.                                                                  TOCValueBytesPtr theValueBytes,
  257.                                                                   ConstValueType dataType, CM_ULONG data,
  258.                                                                   CM_ULONG dataLength);
  259.     /*
  260.     This routine is used to just set the value (theValueBytes) with the specified data. The
  261.     data is placed in theValueBytes as a function of the specified type, dataType.  There
  262.     are 7 types:
  263.      
  264.     (1). Value_NotImm                This is the "normal" case for a non-immediate value data (a
  265.                                                     container offset) and data length.  The value/valueLen (i.e.,
  266.                                                     notImm) variant of a TOCValueBytes is used.
  267.                                                      
  268.     (2). Value_Imm_Chars    All of these use the corresponding imm variant of the ptr to the
  269.     (3). Value_Imm_Long     TOCValueBytes struct passed here.  The data is placed in the
  270.     (4). Value_Imm_Short    field according to type and, for the hell of it, the notImm
  271.     (5). Value_Imm_Byte          valueLen field set accordingly.  Note signed and unsigned are
  272.     (6). Value_Imm_Ptr      treated alike.
  273.                                                      
  274.     (7). Value_GlobalName        This is a special case for global name strings. The data is
  275.                                                     assumed to be a pointer to a global name string.  A global name
  276.                                                     symbol table entry is created (using cmDefineGlobalName()) with
  277.                                                     the string.  The pointer to the symbol table entry is set as
  278.                                                     the value data. Note, a global name symbol table entry also
  279.                                                     has a back pointer to its "owning" TOCValue. THE CALLER MUST
  280.                                                     SET THIS FIELD!  Here we only deal with the value bytes.
  281.                                                      
  282.     The function returns the input theValueBytes pointer as its result.  NULL is returned
  283.     for Value_GlobalName if the allocation fails and an error will have been reported (note,
  284.     as usual we're covering our ass again here).
  285.     */
  286.  
  287.  
  288. TOCValuePtr cmCreateValueSegment(TOCValueHdrPtr theValueHdr, TOCValueBytesPtr value,
  289.                                                                  const CM_USHORT flags);
  290.     /*
  291.     This routine is called to create a new value segment and to fill in its fields with the
  292.     passed parameters.  A pointer to the newly created value segment is returned.  NULL is
  293.     returned if there is an allocation error.
  294.     
  295.     Segments are created generally created for continued values and appended on to the value
  296.     chain whose header is container in a value header.  However, due to such things like
  297.     value inserts a value segment may not necessarily be appended to the end of its chain.
  298.     Thus this routine, which brings a value segment into existence, is a separate routine.
  299.     
  300.     Note, only the segment is created here.  It is up to the caller to chain it to its value
  301.     header and echo the flags in that header.
  302.     */
  303.     
  304.  
  305. TOCValuePtr cmAppendValue(TOCValueHdrPtr theValueHdr, TOCValueBytesPtr value,
  306.                                                     const CM_USHORT flags);
  307.     /*
  308.     This routine takes a pointer to a value definition (the actual bytes) and its flags
  309.     and creates a TOCValue struct which is appended to the specified value header.  The
  310.     function returns the value pointer as its result (i.e. pointer to the newly created
  311.     value).  NULL is returned and an error reported if the allocation of the TOCValue fails.
  312.     
  313.     This routine is used to append actual values to an existing value header.  It is allowed
  314.     to call cmDefineObject() with a NULL value bytes pointer.  In that case an object is 
  315.     created with a value header but no value sublist off of that header.  This routine can
  316.     be called to build that sublist.
  317.     */
  318.     
  319.  
  320. TOCObjectPtr cmDefineObject(ContainerPtr container, CM_ULONG objectID,
  321.                                                        const CM_ULONG propertyID, const CM_ULONG typeID, 
  322.                                                          TOCValueBytesPtr value, const CM_ULONG generation,
  323.                                                         const CM_USHORT flags, const CM_USHORT objectFlags,
  324.                                                         TOCValueHdrPtr *theValueHdr);
  325.     /*
  326.     This routine is called to define a new TOC entry for an object.  We may have either a
  327.     new object (id) or a preexisting one for which a new property and value are to be 
  328.     defined.  All the fields for a TOC entry are passed.  The objectFlags indicate the
  329.     type of the object (more about this later).
  330.     
  331.   Note, the value associated with the property is appended to the the end of the
  332.     property's value list.  The caller has the option of getting the pointer to the value
  333.     header (theValueHdr) when theValueHdr is not passed as NULL.
  334.     
  335.     The function returns a pointer to the object if it was successfully created and NULL if
  336.     it wasn't.  An error is reported if NULL is returned.  Note, while error calls are not
  337.     supposed to return we assume here they due just to be safe!
  338.     
  339.     The objectFlags determine how we treat the object and all the object fields (the other
  340.     parameters).  There are four possible objectFlags:
  341.     
  342.     (1). UndefinedObject        Set if the object is to be created, but we don't yet know what
  343.                                                     its TOC entries are.  Basically a null object (or placeholder)
  344.                                                     is created.  It is an incomplete object in that there are no
  345.                                                     properties or types chained to the object (yet).  This flag may
  346.                                                     be used in combination with the others if we know that the 
  347.                                                     object ID corresponds to a property, type, or neither.
  348.                                                      
  349.     (2). ObjectObject                This flags is used when we don't know the type of the object but
  350.                                                     we know a property and type for it.  If the object already exists
  351.                                                     and it's undefined (UndefinedObject) it is now considered as
  352.                                                     defined.  If it was an undefined property or type, it now becomes
  353.                                                     a defined property or type.  Of course, duplicate definitions
  354.                                                     are an error.
  355.     
  356.     (3). PropertyObject            This is similar to ObjectObject, but here we know the object is
  357.                                                     for a property.  It has to either not exist previously, or was
  358.                                                   previously flagged as UndefinedObject and PropertyObject.
  359.     
  360.     (4). TypeObject                    Same as PropertyObject, but for type objects.
  361.  
  362.     This routine is the "main control" of Container Manager object creation.  It is used
  363.     for "normal" object creation and while loading in a TOC from a preexisting container
  364.     (i.e., from loadTOC()). After loadTOC(), or if we are writing and never do a loadTOC()
  365.     we have the "normal" case.  "We control the horizontal. Do not adjust your TV set". We
  366.     always know what we are creating (yeah, I got a bridge to sell you too).  So we never
  367.     have undefined entries.  Thus in that case we can link the objects to their master lists. 
  368.  
  369.     For loadTOC() however, we are creating objects as we see thier id's in each TOC entry as
  370.     we read them.  We can have forward references to undefined and yet to be fully
  371.     created objects and backward references to existing objects.  We can also have multiple
  372.     properties and values for the same object.  Hence the flags and all they imply.  We also
  373.     do not link the objects.  That is delayed until the TOC is completely read in.  At that
  374.     point the entire TOC is walked sequentially and the links built.  We can also do some
  375.     additional validation to make sure that everything is defined after the read in.
  376.     */
  377.  
  378.  
  379. void cmMarkValueDeleted(ContainerPtr container, TOCValueHdrPtr theValueHdr,
  380.                                                 CMBoolean deleteHdr);
  381.     /*
  382.     This routine takes a pointer to a value header in the specified container and deletes it.
  383.     If the value was the only one for its property, the property is also deleted.
  384.     
  385.     Note, properties and values actually have their memory freed up.  The value headers are
  386.     placed on the deletedValues list to keep them around, but out of the TOC.  This is to
  387.     prevent dangling references from API user "refNum"s, because it is value header pointers
  388.     that we give to the user as those "refNum"s.  Such value headers are marked as "deleted"
  389.     to prevent future use by the user.
  390.     
  391.     The moving of the deleted value headers to the deletedValues list can be suppressed by 
  392.     passing the deleteHdr parameter as true.  Its memory is simply freed along with the rest.
  393.     This is used currently in only one place for error recovery when dynamic value setup
  394.     fails.  There we want to free all the dynamic value layers (which are headers), and
  395.     finally the base "real" value itself.  It is that final value that is passed to here to
  396.     get rid of.
  397.     */
  398.  
  399.  
  400. void cmDeleteProperty(ContainerPtr container, TOCPropertyPtr theProperty);
  401.     /*
  402.     This routine takes a pointer to a property in the specified container and deletes it and
  403.     all its values.
  404.     
  405.     Note, properties and values actually have their memory freed up.  The value headers are
  406.     placed on the deletedValues list to keep them around, but out of the TOC.  This is to
  407.     prevent dangling references from API user "refNum"s, because it is value header pointers
  408.     that we give to the user as those "refNum"s.  Such value headers are marked as "deleted"
  409.     to prevent future use by the user.
  410.     */
  411.  
  412.  
  413. void cmMarkObjectDeleted(ContainerPtr container, TOCObjectPtr theObject);
  414.     /*
  415.     This routine is called to remove an entire object from the TOC for the specified
  416.     container.  All its associated structures (properties and values) are made unavailable
  417.     from the TOC.  The space for the object is NOT freed. The object is placed on a list of
  418.     deleted objects and marked as deleted.  By doing it this way, any outstanding "refNum"s
  419.     we gave the API user (which are pointers to this stuff) will still be "valid" (sort of
  420.     -- at least not looking at garbage).
  421.     */
  422.     
  423.     
  424. void cmFreeTOC(ContainerPtr container, void **toc);
  425.     /*
  426.     This routine is called to free all the structures in a TOC. For updating, a container may
  427.     have its own TOC and the target TOC.  Thus the TOC pointer is an explicit parameter. It
  428.   is passed as a pointer to the toc pointer because freeing the TOC will NULL out the
  429.   caller's pointer.
  430.     
  431.     All memory for objects, properties, and types is freed.  On return the toc pointer in the
  432.     container is NULL as well as all the master link head/tail pointers.
  433.     */
  434.  
  435.  
  436. TOCPropertyPtr cmGetObjectProperty(TOCObjectPtr theObject, CM_ULONG propertyID);
  437.     /*
  438.   This routine takes a pointer to an object and scans its properties for the specified ID.
  439.   The pointer to the property on the object's property chain is returned if found.  NULL is
  440.   returned if not found.
  441.     */
  442.  
  443.  
  444. TOCValueHdrPtr cmGetPropertyType(TOCPropertyPtr theProperty, CM_ULONG typeID);
  445.     /*
  446.     This routine takes a pointer to a object's property and scans its value headers for one
  447.     containing the specified type ID.  The pointer to the value header is returned if found.
  448.     NULL is returned if not found.
  449.     */
  450.     
  451.     
  452. CM_ULONG cmGet1ValueSize(TOCValuePtr theValue);
  453.     /*
  454.     This routine takes a pointer to a value (NOT a value header -- continued values are not
  455.     worried about here) and returns the size represented by that value.  For non-immediate
  456.     values we simply return the length field from the value.  Immediate value sizes are
  457.     dependent on their type.
  458.     */
  459.  
  460.  
  461. #if CMVALIDATE
  462. #define cmValidateCMObject(object)          cmValidateCMObjects((CMObject)(object),   0xFFFFU)
  463. #define cmValidateCMProperty(property) cmValidateCMObjects((CMObject)(property), PropertyObject)
  464. #define cmValidateCMType(type)                  cmValidateCMObjects((CMObject)(type),          TypeObject)
  465. CMBoolean cmValidateCMValue(CMValue value);
  466. CMBoolean cmValidateCMObjects(CMObject object, CM_USHORT objectFlags);
  467.     /*
  468.     CMObject, CMProperty, CMType, and CMValue "refNum"s in the API are implemented in the
  469.     Container Manager as pointers to TOCObject structs (CMObject, CMProperty, and CMType) and
  470.     TOCValueHdr structs (CMValue).  These routines is used to filter "bad" object "refNum"s
  471.     passed to the higher level API interface  ("CM...") routines.  False is returned if the
  472.     object, property, type or value is considered as "bad" and true otherwise.
  473.     
  474.     As currently implemented we return false but do NOT report an error for NULL pointers.
  475.     That is because we return NULL from everthing we error out of earlier.  The NULL test is
  476.     just protection from letting such pointer from ever being used.
  477.     
  478.     Another check we do without reporting an error is on the container pointer.  The refNums
  479.     have a pointer to their container.  The container has a special pointer pointing to 
  480.     itself.  We check against this pointer.  If we think we don't have a valid container
  481.     pointer then we assume we have a bad refNum and return false.  No error can be reported
  482.     because, wiut a container pointer, there is no way to do it!
  483.     
  484.     We DO report an error for attempting to use a deleted object, property, type, or value.
  485.     Deleted TOCObject's and TOCValueHdr's are NOT freed.  Rather they are put on a list
  486.     (separate lists) of deleted objects or value headers and flagged as deleted just for the
  487.     purpose of testing by these routines.  If we had freed them, then we would be getting
  488.     pointers to "garbage".  By keeping them around we have valid pointers and we can do the
  489.     test.
  490.     
  491.     For types and properties we also validate that such "refNum"s are indeed types or
  492.     properties.
  493.     
  494.     Note, for objects, types, and properties, the macros defined above should be used.  They
  495.     expand to calls to cmValidateCMObjects().
  496.     */
  497. #endif
  498.     
  499.     
  500. enum TOCWalkReturns {                                    /* cmWalkThroughEntireTOC() action return codes:    */
  501.     WalkNextTOCObject,                                    /*         do next object                                                            */
  502.     WalkNextTOCProperty,                                /*                        property                                                        */
  503.     WalkNextTOCValueHdr,                                /*                        value header                                                */
  504.     WalkNextTOCValue                                        /*                        value segment                                                */
  505. };
  506. typedef enum TOCWalkReturns TOCWalkReturns;
  507.     /*
  508.     The WalkReturns are the return codes that each cmWalkThroughEntireTOC() action routine is
  509.     to return to direct the walking through the TOC.  cmWalkThroughEntireTOC() is described
  510.     below.  It takes action routines to apply to each data structure of the TOC as it is
  511.     walked.  These return codes allow tighter control over the walking.
  512.     
  513.     The action routines should return the codes shown in the following table:
  514.             
  515.                       Walk...  NextTOCObject | NextTOCProperty | NextTOCValueHdr | NextTOCValue
  516.         ===============|===============|=================|=================|==============
  517.         objectAction   |  next object  |  next property* |                 |
  518.         propertyAction |  next object  |  next property  | next value hdr* |
  519.         valueHdrAction |  next object  |  next property  | next value hdr  | next segment*
  520.         valueAction    |  next object  |  next property  | next value hdr  | next segment*
  521.         ---------------+---------------+-----------------+-----------------+--------------
  522.         
  523.         * The entries marked with "*" are the returns that should be used in the normal case
  524.           to fully walk each data structure of the TOC.  Those not marked with "*" are for
  525.             special cases to abort the walk to go to the next indicated data structure.  Walks
  526.             are sequential through the TOC by ascending object ID.  Thus skipping a particular
  527.             walk of one structure only makes sense if the skip is possible.  That is the reason
  528.             not all returns are allowed in all action routines.  In reality, only the non-starred
  529.             returns are checked on return from an action routine. So the default is the starred
  530.             return (i.e., keep walking normally) if a non-starred is not returned.
  531.         
  532.     */
  533.  
  534.  
  535. int cmWalkThroughEntireTOC(ContainerPtr container, void *toc, 
  536.                                                      CMObjectID startingID, CMObjectID endingID,
  537.                                                      CMRefCon refCon,
  538.                                                       TOCWalkReturns (*objectAction)(ContainerPtr container, TOCObjectPtr theObject, CMRefCon refCon),
  539.                                                       TOCWalkReturns (*propertyAction)(ContainerPtr container, TOCPropertyPtr theProperty, CMRefCon refCon),
  540.                                                       TOCWalkReturns (*valueHdrAction)(ContainerPtr container, TOCValueHdrPtr theValueHdr, CMRefCon refCon),
  541.                                                       TOCWalkReturns (*valueAction)(ContainerPtr container, TOCValuePtr theValue, CMRefCon refCon));
  542.     /*
  543.     This routine is called to walk the entire specified TOC by ascending object ID, starting 
  544.     with object ID's greater than or equal to the startingID and less than or equal to
  545.     endingID, and to call an action routine appropriate for each kind of structure: object,
  546.     property, value header, and value.  
  547.     
  548.     Pointers to the four action routines are passed with headers as shown in the definition. 
  549.     If a pointer is passed as NULL, no action will be performed for the corresponding
  550.     structure.  Each function has return codes (type TOCWalkReturns) that direct the walking
  551.     through the TOC.    The action routines should return the codes shown in the following
  552.     table:
  553.              
  554.                          Walk...  NextTOCObject | NextTOCProperty | NextTOCValueHdr | NextTOCValue
  555.          ===============|===============|=================|=================|==============
  556.          objectAction   |  next object  |  next property* |                 |
  557.          propertyAction |  next object  |  next property  | next value hdr* |
  558.          valueHdrAction |  next object  |  next property  | next value hdr  | next segment*
  559.          valueAction    |  next object  |  next property  | next value hdr  | next segment*
  560.          ---------------+---------------+-----------------+-----------------+--------------
  561.  
  562.     The entries marked with "*" are the returns that should be used in the normal case to
  563.     fully walk each data structure of the TOC.  Those not marked with "*" are for special
  564.     cases to abort the walk to go to the next indicated data structure.  Walks are sequential
  565.     through the TOC by ascending object ID.  Thus skipping a particular walk of one structure
  566.     only makes sense if the skip is possible.  That is the reason not all returns are allowed
  567.     in all action routines.  In reality, only the non-starred returns are checked on return
  568.     from an action routine. So the default is the starred return (i.e., keep walking normally)
  569.     if a non-starred is not returned.
  570.     
  571.     A "refCon" is also passed which the caller can use as a communication facility to convey
  572.     additional info to the action routines.  
  573.     
  574.     This function returns 0 to indicate successful completion, and non-zero otherwise.  Thus
  575.     if AbortWalkThroughEntireTOC(x) is used to abort processing, the x should be a positive
  576.     non-zero integer.
  577.     
  578.     Note, if the property, value header, and value action routines are supplied as NULL,
  579.     then cmWalkThroughEntireTOC() is functionally equivalent to cmForEachObject() which just
  580.     applies a single action routine to the objects.  Thus if only the objects are to be
  581.     walked, it is recommended that cmForEachObject() be used instead of
  582.     cmWalkThroughEntireTOC().
  583.     
  584.     Note also, this routine uses cmForEachObject() to walk the TOC objects with walkObject()
  585.     defined above as the action routine.  It handles the walking of the structures "below"
  586.     the object level. We use the refCon parameter to cmForEachObject() to communicate to
  587.     walkObject() all the action routine pointers and the caller's refCon.  In particular,
  588.     the refCon is a pointer to the container.  In the container is a pointer BACK to a local
  589.     data structure we set up here with all the info.
  590.     */
  591.  
  592.  
  593. #define AbortWalkThroughEntireTOC(x) longjmp(*(jmp_buf *)container->tocActions, x)
  594.     /*
  595.     Use this in routines passed to cmWalkThroughEntireTOC() to abort the walk. The value of x
  596.     is returned from cmWalkThroughEntireTOC(). It should be non-zero since 0 is the "success"
  597.     return value for cmWalkThroughEntireTOC().
  598.     */
  599.  
  600.  
  601. int cmWalkObject(ContainerPtr container, TOCObjectPtr theObject, CMRefCon refCon,
  602.                                  TOCWalkReturns (*objectAction)(ContainerPtr container, TOCObjectPtr theObject, CMRefCon refCon),
  603.                                  TOCWalkReturns (*propertyAction)(ContainerPtr container, TOCPropertyPtr theProperty, CMRefCon refCon),
  604.                                  TOCWalkReturns (*valueHdrAction)(ContainerPtr container, TOCValueHdrPtr theValueHdr, CMRefCon refCon),
  605.                                  TOCWalkReturns (*valueAction)(ContainerPtr container, TOCValuePtr theValue, CMRefCon refCon));
  606.     /*
  607.     This routine is called to walk a single object (theObject) and call an action routine
  608.     appropriate for each kind of structure: object, property, value header, and value. 
  609.     Pointers to the four action routines are passed with headers as shown in the definition.
  610.     If a pointer is passed as NULL, no action will be performed for the corresponding
  611.     structure.  The returns are the same as cmWalkThroughEntireTOC().  See it for further
  612.     details.
  613.     
  614.     A "refCon" is also passed which the caller can use as a communication facility to convey
  615.     additional info to the action routines. 0 is returned to indicate successfull completion.
  616.     Use the AbortWalkObject(x) (a macro) in an action routine to abort the walk.  The "x" is
  617.     a integer which is returned from cmWalkObject() so it should not be 0.
  618.     */
  619.  
  620.  
  621. #define AbortWalkObject(x) longjmp(*(jmp_buf *)container->tocActions, x)
  622.     /*
  623.     Use this in routines passed to cmWalkObject() to abort the walk. The value of x is
  624.     returned from cmWalkObject(). It should be non-zero since 0 is the "success" return value
  625.     for AbortWalkObject().
  626.     */
  627.  
  628. void cmFreeProperties(TOCObjectPtr theObject, CMRefCon refCon);
  629.  
  630. /*
  631.  
  632.  This routine is called to unconditionally free all the properties for an
  633.  objects and the values and other data structures associated with those properties.  It is
  634.  done when an TOC is deleted, i.e, for cmFreeTOC().
  635.  
  636.  Note, here we can just free the properties and associated data structures.  We don't have
  637.  to respect the fact that they are on a list whose header belongs to the the object.  That
  638.  is because we know we are going to delete the object too.
  639.  
  640.  This routine differs from deleteProperties(), and cmDeleteProperty() in that we just free
  641.  the data.  There is no list maintenance and we do not have to worry about moving deleted
  642.  objects or value headers to their delete lists.
  643.  
  644.  Note, this "static" is intentionally left to default memory model under DOS since it is
  645.  passed as a function pointer to cmDestroyTOC().
  646. */
  647.  
  648.                                                           CM_END_CFUNCTIONS
  649. #endif
  650.